package juc;

import java.util.Properties;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 所谓的阻塞队列就是在队列满了之后会堵塞往里面写入的数据，当队列为空的时候会堵塞删除数据的请求
 *
 * @Author linhao
 * @Date created in 3:37 下午 2021/3/28
 */
public class BlockQueueDemo {


    public static void testArrayBlockQueue() throws InterruptedException {
        //公平的 基于 数组实现的堵塞队列
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(10, true);
        for (int i = 0; i < 14; i++) {
            //使用add操作满了之后会抛出异常
//            arrayBlockingQueue.add(i);
            //使用offer，如果满了则直接返回false 不会出现异常
//            arrayBlockingQueue.offer(i);
            //使用put会一直堵塞队列内容
            arrayBlockingQueue.put(i);
            //如果没有元素就出现异常
            arrayBlockingQueue.remove();
            //如果没有元素就返回null
            arrayBlockingQueue.poll();
            //如果没有元素这里就会堵塞
            arrayBlockingQueue.take();
        }
        System.out.println(arrayBlockingQueue.size());
    }

    public static void testLinkedListBlockQueue() throws InterruptedException {
        LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue();
        linkedBlockingQueue.add(1);
        linkedBlockingQueue.offer(1);
        linkedBlockingQueue.put(2);
        linkedBlockingQueue.remove();
        linkedBlockingQueue.poll();
        //take会堵塞
        linkedBlockingQueue.take();
    }

    public static void testPriorityBlockQueue() throws InterruptedException {
        PriorityBlockingQueue priorityBlockingQueue = new PriorityBlockingQueue();
        priorityBlockingQueue.add(1);
        priorityBlockingQueue.offer(1);
        priorityBlockingQueue.put(1);

        priorityBlockingQueue.remove();
        priorityBlockingQueue.poll();
        priorityBlockingQueue.take();
    }

    public static void testDelayQueue() throws InterruptedException {
        DelayQueue delayQueue = new DelayQueue();
        delayQueue.add(new DelayTask("task-1", 3000));
        delayQueue.add(new DelayTask("task-2", 3000));
        DelayTask delayTask = (DelayTask) delayQueue.take();
        DelayTask delayTask2 = (DelayTask) delayQueue.take();
        System.out.println(delayTask.toString());
        System.out.println(delayTask2.toString());
    }

    public static void testSynchronousQueue() throws InterruptedException {
        SynchronousQueue synchronousQueue = new SynchronousQueue();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(500);
                    int result = (int) synchronousQueue.take();
                    System.out.println(result);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        //put进去之后当前线程就会进入堵塞状态
        synchronousQueue.put(1);
    }

    public static void main(String[] args) throws InterruptedException {
        testSynchronousQueue();
    }
}

class DelayTask implements Delayed {

    private long currentTime = System.currentTimeMillis();
    protected final String taskName;
    protected final long scheduleTime;

    protected final AtomicInteger taskCount = new AtomicInteger(0);

    public DelayTask(String taskName, int timeCost) {
        this.taskName = taskName;
        this.scheduleTime = System.currentTimeMillis() + timeCost;
    }

    //当这里是个负数的时候就会出队列
    @Override
    public long getDelay(TimeUnit unit) {
        return this.scheduleTime - System.currentTimeMillis();
    }

    @Override
    public int compareTo(Delayed o) {
        return (int) (this.scheduleTime - ((DelayTask) o).scheduleTime);
    }

}
